
#include <Arduino.h>
#include <EEPROM.h>
#include <avr/pgmspace.h>
#include "eepromutil.h"



//注意,arduino leonard的EEPROM只有1KB,所以所写的自定义程序大小不能大于1KB,其中的38个节字用于保存自定义按键功能了,剩下的EEPROM才是用来编程的
//
//const char gameBtns[12] = {10,5,7,9,11,4,6,8,A1,A2,A3,A4};   //初始值按键值
//
//char realeBtn[12] = {10,5,7,9,11,4,6,8,A1,A2,A3,A4};  //真实12按键和按键顺序对应值
//char btnTypes[12] = {0};                              //12按键功能类型,0:gamepad按键,1:左右摇杆切换功能按键或者摇杆模拟鼠标按键,2:摇杆方向功能键,3:普通电脑键盘,4:鼠标方向按键,5:组合必杀按键或自定义程序值
//
//unsigned char btnRepeatFlog[2] = {0};                       //按键是否为按下后自动重复按压,按位操作,如果相应位为1表示是自动重复按下,0表示没有自动重复按下
//
////12按键对应值,
////当相应btnTypes为0时,值对应1~32个支持的按键值,
////当相应btnTypes为1时,值为1时表示此键功能为左右摇杆切换,值为2时表示摇杆模拟电脑鼠标,值为3时表示摇杆模拟电脑方向键,值为4时表示摇杆模拟电脑WSAD四个按键,5:摇杆为手柄上的4方向按键
////当相应btnTypes为2时,值对应摇杆的方向值,x正向值为1,x向方向时值为2,y正方向时值为3,y负方向时值为4
////当相应btnTypes为3时,值对应电脑ASCII码按键值
////当相应btnTypes为4时,值为模拟电脑鼠标的相对移动值
////当相应btnTypes为5时,值为组合必杀定义功能选择值,组合必杀功能需要先定义和设置后才可以使用,此功能也可以简单理解为编程值
//char btnVal[12] = {0};                                

int baseProAddr = BTNEEPROMSIZE + ADCEEPROMSIZE;

int nextProAddr = baseProAddr;  //下一个程序开始地址

char rBtn[12];
char tBtn[12];
char vBtn[12];
uint16_t flogBtn;
char repeatDelaytime; //重复按下的延时时间
char xyFlog;   //bit0:y轴是否反向,bit1:x轴是否反向

//adc
char isInit;                //是否已设置过值
unsigned char adc_max[8];   //摇杆检测到的最大值
unsigned char adc_min[8];   //摇杆检测到的最小值


void saveADCObj()
{
  int eeAddress = 0;
//  EEPROM.put(eeAddress, m_adcobj);
  EEPROM.write(eeAddress, isInit);
  eeAddress += 1;
  for(int i = 0;i<8;i++){
    EEPROM.write(eeAddress+i, adc_max[i]);
  }
  eeAddress += 8;
  for(int i = 0;i<8;i++){
    EEPROM.write(eeAddress+i, adc_min[i]);
  }
  
  
}

void loadADCObj()
{
  int eeAddress = 0;
//  EEPROM.get(eeAddress, m_adcobj);
  isInit = EEPROM.read(eeAddress);
  eeAddress += 1;
  for(int i = 0;i<8;i++){
    adc_max[i] = EEPROM.read(eeAddress+i);
  }
  eeAddress += 8;
  for(int i = 0;i<8;i++){
    adc_min[i] = EEPROM.read(eeAddress+i);
  }
}

void saveBtnData()
{
  //char rBtn[12];
//char tBtn[12];
//char vBtn[12];
//uint16_t flogBtn;
//char repeatDelaytime; //重复按下的延时时间
//char xyFlog;   //bit0:y轴是否反向,bit1:x轴是否反向
    int eeAddress = ADCEEPROMSIZE;
    for(int i=0;i<12;i++){
      EEPROM.write(eeAddress+i, rBtn[i]);
    }
    eeAddress += 12;
    for(int i = 0;i<12;i++){
      EEPROM.write(eeAddress+i, tBtn[i]);
    }
    eeAddress += 12;
    for(int i = 0;i<12;i++){
      EEPROM.write(eeAddress+i, vBtn[i]);
    }
    eeAddress += 12;
    EEPROM.put(eeAddress, flogBtn);
    eeAddress += 2;
    EEPROM.write(eeAddress, repeatDelaytime);
    eeAddress += 1;
    EEPROM.write(eeAddress, xyFlog);
}

void loadBtnData()
{
  //char rBtn[12];
//char tBtn[12];
//char vBtn[12];
//uint16_t flogBtn;
//char repeatDelaytime; //重复按下的延时时间
//char xyFlog;   //bit0:y轴是否反向,bit1:x轴是否反向
    int eeAddress = ADCEEPROMSIZE;
    for(int i=0;i<12;i++){
      rBtn[i] = EEPROM.read(eeAddress+i);
    }
    eeAddress += 12;
    for(int i = 0;i<12;i++){
      tBtn[i] = EEPROM.read(eeAddress+i);
    }
    eeAddress += 12;
    for(int i = 0;i<12;i++){
      vBtn[i] = EEPROM.read(eeAddress+i);
    }
    eeAddress += 12;
    EEPROM.get(eeAddress, flogBtn);
    eeAddress += 2;
    repeatDelaytime = EEPROM.read(eeAddress);
    eeAddress += 1;
    xyFlog = EEPROM.read(eeAddress);
}

const char pinNumber[12] PROGMEM = {10,5,7,9,11,4,6,8,A1,A2,A3,A4};
void resetEEPROM()
{
//    char pinNumber[12] = {10,5,7,9,11,4,6,8,A1,A2,A3,A4};
    
    for(int i = 0;i<12;i++){
      char tmp = pgm_read_byte(&pinNumber[i]);
      rBtn[i] = tmp;
      vBtn[i] = i+1;
      tBtn[i] = 0;
    }
    //m_btnobj.rBtn = {10,5,7,9,11,4,6,8,A1,A2,A3,A4};
    //m_btnobj.tBtn = {0};
    flogBtn = 0x0000;
    xyFlog = 0x02; //bit0:y轴是否反向,bit1:x轴是否反向
    //m_btnobj.vBtn =  {1,2,3,4,5,6,7,8,9,10,11,12};
    repeatDelaytime = 50;

    saveBtnData();

}


void initEEPROM()
{
  loadBtnData();
  if(rBtn[0] == 0)
  {
    resetEEPROM();
  }
}


//获取程序地址和程序长度
ProObj getNextProFromEEPROM(bool isStart)
{
  ProObj proobjtmp;
  unsigned int prolengh = 0;
  if(isStart) //获取第一个程序起始地址和程序长度
  {
    nextProAddr = baseProAddr;
    EEPROM.get(nextProAddr, prolengh);
    nextProAddr += sizeof(unsigned int);
    proobjtmp.addr = nextProAddr;
    proobjtmp.progremLenth = prolengh;
    return proobjtmp;
  }else{//获取下一个程序起始地址和程序长度
    EEPROM.get(nextProAddr, prolengh);
    nextProAddr += sizeof(unsigned int);
    proobjtmp.addr = nextProAddr;
    proobjtmp.progremLenth = prolengh;
    nextProAddr += prolengh;
    return proobjtmp;
  }
  
}
